from fastapi import APIRouter, HTTPException, status, Depends, Body
from typing import Optional
from pydantic import BaseModel
from sqlalchemy.orm import Session
from datetime import datetime
import base64
from pathlib import Path
from tools.baidu_ocr import ocr_idcard
from routers.dependencies import get_current_user
from models.models import User, IdentityVerification
from database import get_db

# 上传目录配置
UPLOAD_DIR = Path("uploads/id_cards")
UPLOAD_DIR.mkdir(parents=True, exist_ok=True)

router = APIRouter(prefix="/api/identity", tags=["实名认证"])


@router.get("/status")
async def get_verification_status(
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    查询实名认证状态
    
    返回：
    - status: 0-待审核, 1-已通过, 2-已拒绝, null-未提交
    """
    try:
        verification = db.query(IdentityVerification).filter(
            IdentityVerification.user_id == current_user.id
        ).first()
        
        if not verification:
            return {
                "code": "success",
                "status": None,
                "message": "未提交实名认证"
            }
        
        status_map = {
            0: "待审核",
            1: "已通过",
            2: "已拒绝"
        }
        
        return {
            "code": "success",
            "status": verification.status,
            "message": status_map.get(verification.status, "未知状态"),
            "real_name": verification.real_name if verification.status == 1 else None,
            "verified_at": verification.verified_at.isoformat() if verification.verified_at else None,
            "reject_reason": verification.reject_reason if verification.status == 2 else None,
            "created_at": verification.created_at.isoformat()
        }
    except Exception as e:
        import traceback
        error_msg = f"{type(e).__name__}: {str(e)}"
        print(f"[ERROR] Get status error: {error_msg}")
        traceback.print_exc()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"查询失败: {error_msg}"
        )


class OcrRequest(BaseModel):
    """OCR识别请求"""
    image_base64: str
    id_card_side: str = "front"


class VerifyRequest(BaseModel):
    """实名认证提交请求"""
    name: str
    id_number: str
    front_image_base64: Optional[str] = None
    back_image_base64: Optional[str] = None


@router.post("/ocr")
async def ocr_identity(
    request: OcrRequest = Body(...),
    current_user: User = Depends(get_current_user)
):
    """
    OCR识别身份证接口
    
    仅识别并返回结果，不保存到数据库
    """
    try:
        print("\n" + "=" * 60)
        print("[INFO] OCR request received")
        print(f"   User ID: {current_user.id}")
        print(f"   ID card side: {request.id_card_side}")
        print("=" * 60 + "\n")
        
        if not request.image_base64:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="未提供图片数据"
            )
        
        # 解码 Base64 图片
        import base64 as _b64
        try:
            image_bytes = _b64.b64decode(request.image_base64)
        except Exception as e:
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=f"图片Base64解码失败: {str(e)}"
            )
        
        # 调用百度 OCR
        print("[INFO] Calling Baidu OCR API...")
        result = ocr_idcard(image_bytes, request.id_card_side)
        
        # 检查 OCR 错误
        if result.get("error"):
            error_msg = result.get('message', '未知错误')
            print(f"[ERROR] OCR failed: {result}")
            raise HTTPException(
                status_code=status.HTTP_502_BAD_GATEWAY,
                detail=f"OCR识别失败: {error_msg}"
            )
        
        # 检查百度 API 错误码
        if "error_code" in result:
            error_code = result.get("error_code")
            error_msg = result.get("error_msg", "未知错误")
            print(f"[ERROR] Baidu OCR error: code={error_code}, msg={error_msg}")
            
            # 根据错误码返回友好提示
            user_msg = error_msg
            if error_code == 18:
                user_msg = "OCR调用次数已达限制，请稍后再试或手动填写信息"
            elif error_code == 17:
                user_msg = "OCR调用次数已用完，请明天再试或手动填写信息"
            elif error_code == 216015:
                user_msg = "图片格式不正确，请重新上传"
            elif error_code == 216200:
                user_msg = "图片中未检测到身份证，请重新拍照"
            
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail=user_msg
            )
        
        # 提取关键字段
        extracted = result.get("extracted", {})
        print(f"[SUCCESS] OCR completed: name={extracted.get('name')}, id_number={extracted.get('id_number')}")
        
        return {
            "code": "success",
            "message": "识别成功",
            "data": extracted
        }
    except HTTPException as he:
        raise
    except Exception as e:
        import traceback
        error_msg = f"{type(e).__name__}: {str(e)}"
        print(f"[ERROR] OCR error: {error_msg}")
        traceback.print_exc()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"OCR处理失败: {error_msg}"
        )


@router.post("/verify")
async def verify_identity(
    request: VerifyRequest = Body(...),
    current_user: User = Depends(get_current_user),
    db: Session = Depends(get_db)
):
    """
    提交实名认证
    
    支持两种方式：
    1. 仅提交姓名和身份证号（人工审核）
    2. 提交姓名、身份证号和照片（可OCR自动验证）
    """
    try:
        print("\n" + "=" * 60)
        print("[INFO] Identity verification submission")
        print(f"   User ID: {current_user.id}")
        print(f"   Name: {request.name}")
        print(f"   ID Number: {request.id_number}")
        print(f"   Has front image: {bool(request.front_image_base64)}")
        print(f"   Has back image: {bool(request.back_image_base64)}")
        print("=" * 60 + "\n")
        
        # 验证身份证号格式
        import re
        if not re.match(r'^[0-9]{17}[0-9Xx]$', request.id_number):
            print(f"[ERROR] Invalid ID number format: {request.id_number}")
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="身份证号格式不正确"
            )
        
        # 检查是否已经提交过
        existing = db.query(IdentityVerification).filter(
            IdentityVerification.user_id == current_user.id
        ).first()
        
        if existing:
            print(f"[INFO] Found existing verification: status={existing.status}")
            if existing.status == 1:  # 已通过
                print(f"[ERROR] User {current_user.id} already verified")
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="您已完成实名认证"
                )
            elif existing.status == 0:  # 审核中，允许更新信息
                print(f"[INFO] User {current_user.id} updating pending verification")
            else:  # 已拒绝，允许重新提交
                print(f"[INFO] User {current_user.id} re-submitting after rejection")
        
        # 保存图片文件
        front_image_path = None
        back_image_path = None
        
        if request.front_image_base64:
            try:
                # 保存正面照片
                front_filename = f"{current_user.id}_front_{int(datetime.now().timestamp())}.jpg"
                front_image_path = UPLOAD_DIR / front_filename
                
                print(f"[DEBUG] Decoding front image, length: {len(request.front_image_base64)}")
                image_bytes = base64.b64decode(request.front_image_base64)
                print(f"[DEBUG] Decoded {len(image_bytes)} bytes")
                
                with open(front_image_path, "wb") as f:
                    f.write(image_bytes)
                
                print(f"[INFO] Saved front image: {front_image_path}")
            except Exception as e:
                print(f"[ERROR] Failed to save front image: {str(e)}")
                import traceback
                traceback.print_exc()
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail=f"保存身份证正面照片失败: {str(e)}"
                )
        
        if request.back_image_base64:
            try:
                # 保存背面照片
                back_filename = f"{current_user.id}_back_{int(datetime.now().timestamp())}.jpg"
                back_image_path = UPLOAD_DIR / back_filename
                
                image_bytes = base64.b64decode(request.back_image_base64)
                with open(back_image_path, "wb") as f:
                    f.write(image_bytes)
                
                print(f"[INFO] Saved back image: {back_image_path}")
            except Exception as e:
                print(f"[ERROR] Failed to save back image: {str(e)}")
        
        # OCR 结果（如果有图片）
        ocr_result = None
        if request.front_image_base64:
            try:
                image_bytes = base64.b64decode(request.front_image_base64)
                ocr_result = ocr_idcard(image_bytes, "front")
                
                # 验证 OCR 结果与提交信息是否一致
                if not ocr_result.get("error") and "error_code" not in ocr_result:
                    extracted = ocr_result.get("extracted", {})
                    ocr_name = extracted.get("name", "").strip()
                    ocr_id = extracted.get("id_number", "").strip()
                    
                    if ocr_name and ocr_name != request.name:
                        print(f"[WARN] Name mismatch: OCR={ocr_name}, Submit={request.name}")
                    if ocr_id and ocr_id != request.id_number:
                        print(f"[WARN] ID mismatch: OCR={ocr_id}, Submit={request.id_number}")
            except Exception as e:
                print(f"[WARN] OCR processing failed: {str(e)}")
                # OCR 失败不影响提交，仍可人工审核
        
        # 保存或更新认证信息
        if existing:
            # 更新已有记录
            existing.real_name = request.name
            existing.id_number = request.id_number
            existing.ocr_result = ocr_result
            existing.status = 0  # 重置为待审核
            existing.reject_reason = None
            existing.updated_at = datetime.now()
            
            # 更新图片路径
            if front_image_path:
                existing.id_card_front_url = str(front_image_path)
            if back_image_path:
                existing.id_card_back_url = str(back_image_path)
            
            print(f"[INFO] Updated existing verification record")
        else:
            # 创建新记录
            verification = IdentityVerification(
                user_id=current_user.id,
                real_name=request.name,
                id_number=request.id_number,
                id_card_front_url=str(front_image_path) if front_image_path else None,
                id_card_back_url=str(back_image_path) if back_image_path else None,
                ocr_result=ocr_result,
                status=0  # 待审核
            )
            db.add(verification)
            print(f"[INFO] Created new verification record")
        
        db.commit()
        
        print(f"[SUCCESS] Identity verification submitted for user {current_user.id}")
        
        return {
            "code": "success",
            "message": "实名认证信息已提交，审核结果将在1-3个工作日内通知您",
            "status": 0,  # 待审核
            "user_id": current_user.id
        }
    except HTTPException as he:
        print(f"[ERROR] HTTPException caught: status={he.status_code}, detail={he.detail}")
        raise
    except Exception as e:
        import traceback
        error_msg = f"{type(e).__name__}: {str(e)}"
        print(f"[ERROR] Verification submission error: {error_msg}")
        print("Full traceback:")
        traceback.print_exc()
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"提交失败: {error_msg}"
        )
